package com.reggie.aspect;

import com.reggie.annotation.AutoFill;
import com.reggie.constant.AutoFillConstant;
import com.reggie.context.BaseContext;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;


import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Aspect
@Component
@Slf4j
//增强带有 AutoFill注释注解的方法
public class AutoFillAspect {


    //定义一个切入点 增强这个路径下的所有类 所有方法 的任意带参方法 同时这个方法需要带有 @AutoFill注解
    @Pointcut("execution(* com.reggie.mapper.*.*(..)) && @annotation(com.reggie.annotation.AutoFill)")
    public void autoFillPointCut() {
    }

    ;

    //前置通知 ,
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) {
        log.info("开启公共字段自动填充.....");

        //获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        //通过签名 获取带有该类型的注解
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
        //获得注解之后 获取注解的参数 也就是操作类型
        String type = autoFill.Type();

        //获取mapper方法中的参数
        Object[] args = joinPoint.getArgs();

        //如果获取的参数为空 或则不存在 就返回
        if (args == null || args.length == 0) {
            return;
        }
        //如果获取到参数 就对这个参数的属性进行增强
        Object entity = args[0];
        //获取当前时间
        LocalDateTime time = LocalDateTime.now();
        //获取当前操作的id
        Long currentId = BaseContext.getCurrentId();
        //如果当前的操作属于Insert 添加操作 (添加人/时间   修改人/修改时间)
        if (type.equals(AutoFillConstant.INSERT)) {
            try {

                Method setCreatTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setCreatUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                //对获取到的entity对象 进行反射赋值
                setCreatTime.invoke(entity, time);
                setUpdateTime.invoke(entity, time);
                setCreatUser.invoke(entity, currentId);
                setUpdateUser.invoke(entity, currentId);
            } catch (Exception ex) {
                log.error("公共字段填充失败");
                ex.printStackTrace();

            }
        } else {
            //获取到的是Update  修改 类型
            try {
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                setUpdateTime.invoke(entity, time);
                setUpdateUser.invoke(entity, currentId);
            } catch (Exception ex) {
                log.error("公共字段填充失败");
                ex.printStackTrace();
            }

        }


    }


}
